package com.lh0811.forge.dependency.basic_code.encrypt;

import org.bouncycastle.crypto.BlockCipher;
import org.bouncycastle.crypto.engines.SM4Engine;
import org.bouncycastle.crypto.modes.CBCBlockCipher;
import org.bouncycastle.crypto.paddings.PaddedBufferedBlockCipher;
import org.bouncycastle.crypto.params.KeyParameter;
import org.bouncycastle.crypto.params.ParametersWithIV;
import org.bouncycastle.util.encoders.Hex;

import java.nio.charset.StandardCharsets;
import java.security.SecureRandom;

public class Sm4Util {

    // 生成随机密钥
    public static String generateRandomKeyHex() {
        byte[] key = new byte[16]; // SM4的密钥大小是128位（16字节）
        new SecureRandom().nextBytes(key);
        return Hex.toHexString(key);
    }

    // 生成随机IV（初始化向量）
    public static String generateRandomIv() {
        byte[] key = new byte[16]; // SM4的密钥大小是128位（16字节）
        new SecureRandom().nextBytes(key);
        return Hex.toHexString(key);
    }

    // 加密方法
    public static String encrypt(String plainText, String keyHex, String hexStr) throws Exception {
        BlockCipher sm4Engine = new SM4Engine();
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(sm4Engine));

        KeyParameter keyParameter = new KeyParameter(Hex.decode(keyHex));
        ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, Hex.decode(hexStr));

        cipher.init(true, parametersWithIV);

        byte[] inputBytes = plainText.getBytes(StandardCharsets.UTF_8);
        byte[] outputBytes = new byte[cipher.getOutputSize(inputBytes.length)];
        int processedBytes = cipher.processBytes(inputBytes, 0, inputBytes.length, outputBytes, 0);
        cipher.doFinal(outputBytes, processedBytes);

        return Hex.toHexString(outputBytes);
    }

    // 解密方法
    public static String decrypt(String cipherTextHex, String keyHex, String hexStr) throws Exception {
        BlockCipher sm4Engine = new SM4Engine();
        PaddedBufferedBlockCipher cipher = new PaddedBufferedBlockCipher(new CBCBlockCipher(sm4Engine));

        KeyParameter keyParameter = new KeyParameter(Hex.decode(keyHex));
        ParametersWithIV parametersWithIV = new ParametersWithIV(keyParameter, Hex.decode(hexStr));

        cipher.init(false, parametersWithIV);

        byte[] cipherBytes = Hex.decode(cipherTextHex);
        byte[] outputBytes = new byte[cipher.getOutputSize(cipherBytes.length)];
        int processedBytes = cipher.processBytes(cipherBytes, 0, cipherBytes.length, outputBytes, 0);
        cipher.doFinal(outputBytes, processedBytes);

        // 去除填充的字节（如果有的话）
        int paddingLength = outputBytes[outputBytes.length - 1];
        return new String(outputBytes, 0, outputBytes.length - paddingLength, StandardCharsets.UTF_8).trim();
    }


    public static void main(String[] args) throws Exception {
        String key = generateRandomKeyHex();
        String ivStr = generateRandomIv();


        System.out.println("key:" + key);
        System.out.println("ivStr:" + ivStr);

        String str = "测试123abcABC#@#$^&&__09.,.\\12```";
        System.out.println("原始Str:" + str);

        // 加密
        String encrypt = Sm4Util.encrypt(str, key, ivStr);
        System.out.println("encrypt:" + encrypt);
        // 解密
        String decrypt = Sm4Util.decrypt(encrypt, key, ivStr);
        System.out.println("decrypt:" + decrypt);
    }


    // 注意：在实际应用中，密钥和IV应该妥善保管，并且不应该硬编码在代码中。
}